/**
 * @file  
 * Functionality to read and store SUBDUE examples.
 */

#ifndef EXPANSION_GRAPH_READER_H
#define EXPANSION_GRAPH_READER_H

#include <fstream>
#include <sstream>

#include <boost/tokenizer.hpp>

#include "example_db.h"
#include "expansion_graph.h"
#include "string_vertex_edge.h"


class ExpansionGraphReader
{
  public:
  bool operator()(std::string Filename, 
                  std::vector<ExpansionGraph<StringVertexEdge, StringVertexEdge>* > &examples)
  {
    // File 
    std::ifstream input_file(Filename.c_str());

    // Line
    std::string line;
  
    // Tokenizing
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
    boost::char_separator<char> sep(" ");
  
    if (input_file.is_open())
      {
        ExpansionGraph<StringVertexEdge, StringVertexEdge> *curr_graph;
        std::map<int, StringVertexEdge*> curr_graph_map;
        bool dirty = false;
        int edge_count = 0;

        while (! input_file.eof())
          {

            std::getline(input_file,line);
            
            tokenizer tokens(line, sep);
            
            tokenizer::iterator tok_iter = tokens.begin();
            
            if (tok_iter != tokens.end())
              {
                if (*tok_iter == "XP")
                  {
                    if(dirty)
                      {
                        examples.push_back(curr_graph);
                        curr_graph_map.erase(curr_graph_map.begin(), 
                                             curr_graph_map.end());
                      }
                    
                  dirty = true;
                  edge_count = 0;
                  }                
                else if (*tok_iter == "v")
                  {
                    tok_iter++;
                    std::istringstream iss(*tok_iter);
                    int id;
                    iss >> id;
                    
                    tok_iter++;
                    std::string payload_data = *tok_iter;
                    
                    StringVertexEdge *curr_vertex = new StringVertexEdge(id, 
                                                                         payload_data);
                    curr_graph->add_vertex(curr_vertex);
                    curr_graph_map.insert(std::pair<int, StringVertexEdge*>(id, curr_vertex));
                  }
                else if (*tok_iter == "u")
                  {
                    edge_count++;
                    
                    tok_iter++;
                    std::istringstream iss1(*tok_iter);
                    int id1;
                    iss1 >> id1;
                    
                    tok_iter++;
                    
                    std::istringstream iss2(*tok_iter);
                    int id2;
                    iss2 >> id2;
                    
                    tok_iter++;
                    std::string payload_data = *tok_iter;
                    
                    StringVertexEdge *curr_edge = new StringVertexEdge(edge_count, 
                                                                       payload_data);
                    
                    curr_graph->add_edge(curr_edge,
                                         (curr_graph_map.find(id1))->second,
                                         (curr_graph_map.find(id2))->second);
                  }
              }
          }
        
        if(dirty)
          examples.push_back(curr_graph);
        
        input_file.close();
        return true;
      }	    
    else 
      return false;
  }
};

#endif // EXPANSION_GRAPH_READER_H
